﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using PandemiaAdmin.Funcionalidad;
using PandemiaAdmin.Entidades;
using PandemiaAdmin.Soporte;

namespace PandemiaAdminNet.Conexiones
{
    public partial class FrmNodos : Form
    {
        private Dictionary<Nodo, Servidor> _dataNodos;
        private Dictionary<Nodo, Servidor> _sinFiltro;

        public FrmNodos()
        {
            InitializeComponent();
            _dataNodos = new Dictionary<Nodo, Servidor>();
            _sinFiltro = new Dictionary<Nodo, Servidor>();
        }


        private void TraerServidores()
        {
            flpServidores.Controls.Clear();
            BLLServidor bll = new BLLServidor(Utilidades.ArchivoServidores);
           
            foreach (Servidor servidor in bll.TraerServidores().OrderBy(s => s.Nombre).ToList())
            {
                Panel pnlServidor = new Panel();
                pnlServidor.Size = pnlPlantilla.Size;
                pnlServidor.Name = "pnlServidor" + servidor.Nombre;
                
                CheckBox chkServidor = new CheckBox();
                chkServidor.Size = chkPlantilla.Size;
                chkServidor.Location = chkPlantilla.Location;
                chkServidor.Text = "";
                chkServidor.Name = "chkServidor" + servidor.Nombre;
                chkServidor.Checked = true;
                pnlServidor.Controls.Add(chkServidor);

                PictureBox pbServidor = new PictureBox();
                pbServidor.Size = pbPlantilla.Size;
                pbServidor.BackgroundImageLayout = ImageLayout.Stretch;
                pbServidor.BackgroundImage = Properties.Resources.Server;
                pbServidor.Location = new Point(28, 3);
                pnlServidor.Controls.Add(pbServidor);

                Label lblServidor = new Label();
                lblServidor.Name = "lblServidor" + servidor.Nombre;
                lblServidor.Location = new Point(60, 8);
                lblServidor.Text = servidor.Nombre;
                pnlServidor.Controls.Add(lblServidor);
                
                flpServidores.Controls.Add(pnlServidor);
            }
        }

        private string ObtenerSelector(Nodo nodo)
        {
            string selector = string.Empty;

            foreach (KeyValuePair<Nodo, Servidor> dataNodo in _dataNodos)
            {
                if (nodo.Alias.Equals(dataNodo.Key.Alias) && nodo.Ip.Equals(dataNodo.Key.Ip) && nodo.NombreMaquina.Equals(dataNodo.Key.NombreMaquina))
                {
                    switch (cboVer.SelectedIndex)
                    {
                        case 0:
                            selector = dataNodo.Key.Alias.ToUpper();
                            break;

                        case 1:
                            selector = dataNodo.Key.Ip;
                            break;

                        case 2:
                            selector = dataNodo.Key.NombreMaquina.ToUpper();
                            break;

                        default:
                            selector = "PIJA";
                            break;
                    }

                    break;
                }
            }

            return selector;
        }

        private string ObtenerSelector(int indice)
        {
            int indiceActual = 0;
            string selector = string.Empty;

            foreach (KeyValuePair<Nodo, Servidor> dataNodo in _dataNodos)
            {
                if (indiceActual == indice)
                {
                    switch (cboVer.SelectedIndex)
                    {
                        case 0:
                            selector = dataNodo.Key.Alias;
                            break;

                        case 1:
                            selector = dataNodo.Key.Ip;
                            break;

                        case 2:
                            selector = dataNodo.Key.NombreMaquina;
                            break;

                        default:
                            break;
                    }

                    break;
                }
                else
                    indiceActual++;
            }

            return selector.ToUpper();
        }

        private void CargarNodo(Nodo nodo)
        {
            Panel pnlNodo = new Panel();
            pnlNodo.Size = new Size(148, 130);
            pnlNodo.BackgroundImage = Properties.Resources.Computadora;
            pnlNodo.BackgroundImageLayout = ImageLayout.Center;
            flpNodos.Controls.Add(pnlNodo);

            Label lblNodo = new Label();
            lblNodo.Text = ObtenerSelector(nodo);
            lblNodo.AutoSize = false;
            lblNodo.Size = new Size(116, 13);
            lblNodo.Location = new Point(16, 25);
            lblNodo.BackColor = Color.Transparent;
            lblNodo.ForeColor = Color.White;
            lblNodo.Font = new Font("Arial", 9, FontStyle.Bold);
            lblNodo.TextAlign = ContentAlignment.MiddleCenter;
            pnlNodo.Controls.Add(lblNodo);

            Button btnNodo = new Button();
            btnNodo.Text = string.Empty;
            btnNodo.Size = new Size(30, 30);
            btnNodo.Location = new Point(58, 50);
            btnNodo.BackgroundImage = Properties.Resources.Encendido;
            btnNodo.BackgroundImageLayout = ImageLayout.Stretch;
            btnNodo.Click += new EventHandler(btnNodo_Click);
            pnlNodo.Controls.Add(btnNodo);

            TextBox txtData = new TextBox();
            txtData.Visible = false;
            txtData.Text = nodo.NombreMaquina + "|" + nodo.Alias + "|" + nodo.Ip;
            pnlNodo.Controls.Add(txtData);
        }

        private void BuscarNodos()
        {
            flpNodos.Controls.Clear();

            if (txtBuscar.TextLength == 0)
                _dataNodos = _sinFiltro.ToDictionary(n => n.Key, s => s.Value);
            else
            {
                _sinFiltro = _dataNodos.ToDictionary(n => n.Key, s => s.Value);

                _dataNodos = (from n in _sinFiltro
                              where (cboVer.SelectedIndex == 0 && n.Key.Alias.ToLower().Contains(txtBuscar.Text.ToLower()))
                              || (cboVer.SelectedIndex == 1 && n.Key.Ip.Contains(txtBuscar.Text))
                              || (cboVer.SelectedIndex == 2 && n.Key.NombreMaquina.ToLower().Contains(txtBuscar.Text.ToLower()))
                              select n).ToDictionary(n => n.Key, s => s.Value);
            }

            foreach (KeyValuePair<Nodo, Servidor> dataNodo in _dataNodos)
                CargarNodo(dataNodo.Key);
        }
        

        private void FrmNodos_Load(object sender, EventArgs e)
        {
            pnlPlantilla.Visible = false;
            cboVer.SelectedIndex = 0;
            flpNodos.Controls.Clear();
            TraerServidores();
        }

        private void btnBuscarNodos_Click(object sender, EventArgs e)
        {
            _dataNodos.Clear();
            flpNodos.Controls.Clear();
            btnBuscarNodos.Enabled = false;
            bgwBuscarNodos.RunWorkerAsync();
        }

        private void bgwBuscarNodos_DoWork(object sender, DoWorkEventArgs e)
        {
            foreach (Control control in flpServidores.Controls)
            {
                Panel pnlServidor = control as Panel;
                CheckBox chkServidor;
                Label lblServidor;

                if (pnlServidor != null)
                    foreach (Control controlServidor in pnlServidor.Controls)
                    {
                        chkServidor = controlServidor as CheckBox;

                        if (chkServidor != null && !chkServidor.Checked)
                            break;

                        lblServidor = controlServidor as Label;

                        if (lblServidor != null)
                        {
                            AdminServidor adminServer = new AdminServidor();

                            if (adminServer.ChequearServidor(lblServidor.Text))
                            {
                                lblServidor.ForeColor = Color.Green;
                                AdminNodos admin = new AdminNodos(lblServidor.Text);

                                foreach (Nodo nodo in admin.TraerNodos())
                                    bgwBuscarNodos.ReportProgress(0, new KeyValuePair<Nodo, Servidor>(nodo, admin.Servidor));
                            }
                            else
                                lblServidor.ForeColor = Color.Red;
                        }
                    }
            }
        }

        private void bgwBuscarNodos_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            KeyValuePair<Nodo, Servidor> dataNodo = (KeyValuePair<Nodo, Servidor>)e.UserState;
            _dataNodos.Add(dataNodo.Key, dataNodo.Value);
            CargarNodo(dataNodo.Key);

            if (pbBusquedaNodos.Value == 100)
                pbBusquedaNodos.Value = 0;

            pbBusquedaNodos.Value += 1;
        }

        private void bgwBuscarNodos_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            btnBuscarNodos.Enabled = true;
            
            if (e.Error != null)
                MessageBox.Show(e.Error.Message, "ERROR", MessageBoxButtons.OK, MessageBoxIcon.Error);

            _sinFiltro = _dataNodos.ToDictionary(n => n.Key, s => s.Value);
            pbBusquedaNodos.Value = 100;
        }

        private void cboVer_SelectedIndexChanged(object sender, EventArgs e)
        {
            int indice = 0;
            txtBuscar.Text = string.Empty;

            if (_dataNodos.Count > 0)
                foreach (Control control in flpNodos.Controls)
                {
                    Panel panel = control as Panel;

                    if (panel == null)
                        continue;

                    foreach (Control controlPanel in panel.Controls)
                    {
                        Label label = controlPanel as Label;

                        if (label == null)
                            continue;

                        label.Text = ObtenerSelector(indice);
                        break;
                    }

                    indice++;
                }
        }

        private void btnNodo_Click(object sender, EventArgs e)
        {
            Button btnNodo = sender as Button;
            Panel pnl = btnNodo.Parent as Panel;
            TextBox txtData = new TextBox();

            foreach (Control control in pnl.Controls)
            {
                txtData = control as TextBox;

                if (txtData != null)
                    break;
            }

            string[] array = txtData.Text.Split(new string[] { "|" }, StringSplitOptions.RemoveEmptyEntries);
            string nombre = array[0];
            string alias = array[1];
            string ip = array[2];

            foreach (KeyValuePair<Nodo, Servidor> dataNodo in _dataNodos)
            {
                if (dataNodo.Key.Alias.Equals(alias) && dataNodo.Key.Ip.Equals(ip) && dataNodo.Key.NombreMaquina.Equals(nombre))
                {
                    FrmNodo frmNodo = new FrmNodo(dataNodo.Key, dataNodo.Value);
                    frmNodo.MdiParent = this.MdiParent;
                    frmNodo.StartPosition = FormStartPosition.CenterScreen;
                    frmNodo.Show();
                    break;
                }
            }
        }

        private void btnBuscar_Click(object sender, EventArgs e)
        {
            BuscarNodos();
        }
    }
}
